Einlesen und Vorbereiten des Datensatzes¶

In [1]:
# benötigte bib importieren

import pandas as pd
import plotly.express as px
import matplotlib.pyplot as plt
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import seaborn as sns
# https://stackoverflow.com/questions/18878083/can-i-use-variables-on-an-ipython-notebook-markup-cell
# https://data-dive.com/jupyterlab-markdown-cells-include-variables
from IPython.display import Markdown as md 


# für dash-app
from jupyter_dash import JupyterDash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output

# Zusatz
from dash import no_update

import warnings
warnings.filterwarnings('ignore')
In [2]:
# datensatz einlesen

df = pd.read_pickle('data_abschlussprojekt_after_preprocessing.pkl')
df.head(2)
Out[2]:
funded_amount loan_amount activity sector use country_code country currency term_in_months lender_count repayment_interval borrower_female borrower_male borrower_unknown borrower_total
0 300.0 300.0 Fruits & Vegetables Food To buy seasonal, fresh fruits to sell PK Pakistan PKR 12 12 irregular 1 0 0 1
1 575.0 575.0 Rickshaw Transportation to repair and maintain the auto rickshaw used ... PK Pakistan PKR 11 14 irregular 2 0 0 2
In [3]:
# sns.pairplot(data=df, corner=True)

Business Frage¶

Die zahl der Ablehungen weiter senken

Plot erstellen - Daten visualisieren um ersten Überblick über unsere Daten zu gewinnen.¶

In [4]:
sector = df.sort_values(['funded_amount'], ascending= False).groupby(by='sector', as_index=False).agg(sum = ('funded_amount', sum))
sector
Out[4]:
sector sum
0 Agriculture 133770635.0
1 Arts 11821055.0
2 Clothing 34805270.0
3 Construction 6321515.0
4 Education 30044920.0
5 Entertainment 1023095.0
6 Food 115089210.0
7 Health 9172250.0
8 Housing 21377100.0
9 Manufacturing 5356650.0
10 Personal Use 14189775.0
11 Retail 90864855.0
12 Services 42966085.0
13 Transportation 9842500.0
14 Wholesale 918900.0
In [5]:
sector = df.groupby(by='sector').agg(sum = ('funded_amount', sum)).sort_values(['sum'], ascending= False)
sector
Out[5]:
sum
sector
Agriculture 133770635.0
Food 115089210.0
Retail 90864855.0
Services 42966085.0
Clothing 34805270.0
Education 30044920.0
Housing 21377100.0
Personal Use 14189775.0
Arts 11821055.0
Transportation 9842500.0
Health 9172250.0
Construction 6321515.0
Manufacturing 5356650.0
Entertainment 1023095.0
Wholesale 918900.0
In [6]:
# <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< sortieren nach größe
pieplot = px.pie(sector
                 ,values='sum'
                 ,names=sector.index
#                  ,labels='sector'
                )

pieplot.show()
In [7]:
# Nach sector gruppiert und nach Summe der Zielbeträge sortiert

df_sector_funded_loan_amount = df.groupby(by='sector', as_index=False).agg(sum_funded_amount = ('funded_amount','sum'), sum_loan_amount = ('loan_amount','sum')).sort_values(['sum_loan_amount'], ascending= False)
df_sector_funded_loan_amount
Out[7]:
sector sum_funded_amount sum_loan_amount
0 Agriculture 133770635.0 143067875.0
6 Food 115089210.0 121606150.0
11 Retail 90864855.0 98122900.0
12 Services 42966085.0 48057450.0
2 Clothing 34805270.0 37300925.0
4 Education 30044920.0 30968525.0
8 Housing 21377100.0 23663950.0
10 Personal Use 14189775.0 14955350.0
1 Arts 11821055.0 12240325.0
13 Transportation 9842500.0 11066900.0
7 Health 9172250.0 9843400.0
3 Construction 6321515.0 6695150.0
9 Manufacturing 5356650.0 5447900.0
5 Entertainment 1023095.0 1389150.0
14 Wholesale 918900.0 995200.0
In [8]:
# Daten an Plot übergeben

barplot = px.bar(data_frame=df_sector_funded_loan_amount
                ,x="sector"
                ,y=["sum_funded_amount", "sum_loan_amount"]
                ,title='Aufstellung der Sektoren je nach Summe der erhaltender und Zielbeträge.'
                ,labels={"sector":"Sektor", "value":"Summe der Beträge in USD", "variable":"Beträge"}
                ,barmode='group'
               )

newnames = {'sum_funded_amount':'Summe erhaltener Beträge', 'sum_loan_amount': 'Summe der Zielbeträge'}
barplot.for_each_trace(lambda t: t.update(name = newnames[t.name]))


barplot.show()
In [9]:
sns.catplot(data=df,kind='count',y='activity',x=None,height=8, aspect=2,
            order=pd.value_counts(df['activity']).iloc[:10].index,alpha=.8,palette='husl')
Out[9]:
<seaborn.axisgrid.FacetGrid at 0x1f16ee9d040>
In [10]:
sns.catplot(data=df
            ,kind='count'
            ,y='country'
            #,x=None
            ,height=8
            ,aspect=2
            ,order=pd.value_counts(df['country']).iloc[:10].index
            ,alpha=.8
            ,palette="Greens_d"
           )
Out[10]:
<seaborn.axisgrid.FacetGrid at 0x1f103563640>

Weitere Plots und Plots zum Bewerten¶

In [11]:
# Nach Verwendungszweck gruppiert/gezählt. Summe erhaltener Beträge ermittelt und nach Anzahl der Verwendungszwecke sortiert

top_usage = 10

df_use_funded_amount_sort_count = df.groupby(by='use' , as_index=False).agg(count = ('use','count'), sum_funded_amount = ('funded_amount','sum')).sort_values(['count'], ascending= False)[:top_usage]
df_use_funded_amount_sort_count
Out[11]:
use count sum_funded_amount
91904 to buy a water filter to provide safe drinking... 5526 878425.0
91890 to buy a water filter to provide safe drinking... 4239 668400.0
49408 kein_verwendungszweck 4232 3901515.0
64369 to build a sanitary toilet for her family 3307 657075.0
6965 To buy a water filter to provide safe drinking... 3245 508750.0
146321 to buy fertilizers and other farm supplies 2253 738975.0
162808 to buy ingredients for her food production bus... 2088 597075.0
140396 to buy feed and vitamins for her pigs 1781 576225.0
364097 to purchase more groceries to sell 1618 591950.0
141341 to buy feeds and other supplies to raise her pigs 1606 501225.0
In [12]:
# Nach Verwendungszweck gruppiert/gezählt und nach Summe erhaltener Beträge sortiert

df_use_funded_amount_sort_funded_amount = df.groupby(by='use', as_index=False).agg(count = ('use','count'), sum_funded_amount = ('funded_amount','sum')).sort_values(['sum_funded_amount'], ascending= False)[:top_usage]
df_use_funded_amount_sort_funded_amount
Out[12]:
use count sum_funded_amount
49408 kein_verwendungszweck 4232 3901515.0
324384 to purchase a solar light and gain access to c... 1405 1097650.0
91904 to buy a water filter to provide safe drinking... 5526 878425.0
116900 to buy cattle 639 754850.0
146321 to buy fertilizers and other farm supplies 2253 738975.0
91890 to buy a water filter to provide safe drinking... 4239 668400.0
64369 to build a sanitary toilet for her family 3307 657075.0
354554 to purchase hybrid seeds and fertilizer to imp... 922 651100.0
25698 To purchase a water filtration system to provi... 429 618150.0
318376 to purchase TerraClear water filters so they c... 798 610975.0

Plot zum Bewerten 1/3¶

In [13]:
# define plotting region (rows, columns)
# setting the dimensions of the plot (width and height)
fig, axes = plt.subplots(3, 1, figsize=(7,25))

#create boxplot in each subplot

clrs = ['red' if (x == 'kein_verwendungszweck') else 'green' for x in df_use_funded_amount_sort_count['use'] ]
sns.countplot(data=df, y='use',palette=clrs,order=df.loc[:,'use'].value_counts().iloc[:top_usage].index,ax=axes[0])
sns.barplot(data=df_use_funded_amount_sort_count, x='sum_funded_amount', y='use', palette=clrs, ax=axes[1])

clrs = ['red' if (x == 'kein_verwendungszweck') else 'green' for x in df_use_funded_amount_sort_funded_amount['use'] ]
sns.barplot(data=df_use_funded_amount_sort_funded_amount,x='sum_funded_amount', y='use', palette=clrs, ax=axes[2])



for i, subplot in enumerate(axes):
    subplot.set_title(f"Top {top_usage} Verwendungszwecke.", size = 20)
    subplot.set_xlabel("Summe erhaltener Beträge", size = 17)
    subplot.set_ylabel("Verwendungszweck", size = 17)
        
    if i == 0:
        subplot.set_title(f"Anzahl der Top {top_usage} Verwendungszwecke", size = 20)
        subplot.set_xlabel("Anzahl der Verwendungszwecke", size = 17)
       

    
# Instead of setting the cell to Markdown, create Markdown from withnin a code cell!
# We can just use python variable replacement syntax to make the text dynamic
md("**Beschreibung** \n- Die Säulendiagramme zeigen die nach Verwendungszweck gruppierten Daten.\n- \
   Erster Subplot zeigt die Top {} Verwendungszwecke an.\n -\
   Hier taucht der fehlende Wert (kein_verwendungszweck) an 2 Stelle auf. Daher wollen wir uns den 2-ten Subplot anschauen\n- \
   Der 2-te Subplot zeigt wieder die Top {} Verwendungszwecke nach Anzahl sortiert an.\n -\
   Auf der x Achse sind jedoch die Summen erhaltener Beträge abgebildet.\n -\
   Hier fällt auf, dass die Projekte die keinen Verwendungszweck enthieleten den größten Teil ausmachen.\n- \
   Der 3-te Subplot zeigt die Top {} Verwendungszwecke nach Summe erhaltener Beträge an.\n -\
   Hier bestätigt es sich nochmal, dass die Projekte die kein Verwendungszweck erhielten größten Teil ausmachen".format(top_usage, top_usage, top_usage))
Out[13]:

Beschreibung

  • Die Säulendiagramme zeigen die nach Verwendungszweck gruppierten Daten.
  • Erster Subplot zeigt die Top 10 Verwendungszwecke an.
    • Hier taucht der fehlende Wert (kein_verwendungszweck) an 2 Stelle auf. Daher wollen wir uns den 2-ten Subplot anschauen
  • Der 2-te Subplot zeigt wieder die Top 10 Verwendungszwecke nach Anzahl sortiert an.
    • Auf der x Achse sind jedoch die Summen erhaltener Beträge abgebildet.
    • Hier fällt auf, dass die Projekte die keinen Verwendungszweck enthieleten den größten Teil ausmachen.
  • Der 3-te Subplot zeigt die Top 10 Verwendungszwecke nach Summe erhaltener Beträge an.
    • Hier bestätigt es sich nochmal, dass die Projekte die kein Verwendungszweck erhielten größten Teil ausmachen
In [14]:
# Nach country gruppiert und nach Summe erhaltener Beträge sortiert

top_countries = 20

df_country_funded_amount_sum = df.groupby(by='country', as_index=False).agg(sum_funded_amount = ('funded_amount','sum')).sort_values(['sum_funded_amount'], ascending= False)[:top_countries]
df_country_funded_amount_sum
Out[14]:
country sum_funded_amount
59 Philippines 54476375.0
34 Kenya 32248405.0
58 Peru 30394850.0
57 Paraguay 29412700.0
22 El Salvador 23357725.0
80 United States 23158540.0
11 Cambodia 18817100.0
7 Bolivia 18276200.0
61 Rwanda 15505600.0
20 Ecuador 14598900.0
78 Uganda 14142675.0
71 Tajikistan 13781775.0
82 Vietnam 13661700.0
15 Colombia 12473775.0
54 Pakistan 12467100.0
55 Palestine 12032025.0
38 Lebanon 11556350.0
2 Armenia 11186675.0
74 The Democratic Republic of the Congo 11020275.0
26 Guatemala 10934975.0
In [15]:
sns.barplot(x='sum_funded_amount', y='country',palette="Greens_d" , data=df_country_funded_amount_sum)
Out[15]:
<AxesSubplot:xlabel='sum_funded_amount', ylabel='country'>
In [16]:
# Daten an Plot übergeben

barplot = px.bar(data_frame=df_country_funded_amount_sum
                ,x="country"
                ,y="sum_funded_amount"
                ,title=f'Top {top_countries} Länder. Sortiert nach Summe ausgezahlter Beträge pro Land. Alle Beträge in USD.'
                ,labels={"country":"Länder", "sum_funded_amount":"Summe ausgezahlter Beträge in USD"} # Beschriftungen anpassen
                ,barmode='group'
               )
barplot.show()
In [17]:
# Die Projekte die mit weniger als 'percent' des Zeilbetrages finanziert worden,
# werden für jedes Land aufsummiert.
percent = 0.5

cond_low_amount = df.loc[:,'funded_amount'] / df.loc[:,'loan_amount'] <= percent
df.loc[cond_low_amount, ['funded_amount','loan_amount']]
Out[17]:
funded_amount loan_amount
313 1300.0 3000.0
648 700.0 2100.0
752 475.0 1200.0
796 450.0 1000.0
815 525.0 1500.0
... ... ...
671199 0.0 25.0
671200 0.0 25.0
671202 0.0 25.0
671203 0.0 25.0
671204 0.0 25.0

26720 rows × 2 columns

In [18]:
df_country_low_amount_sum = df.loc[cond_low_amount,].groupby(by='country', as_index=False).agg(sum_funded_amount = ('funded_amount','sum'), sum_loan_amount = ('loan_amount','sum')).sort_values(['sum_loan_amount'], ascending= False)[:top_countries]
df_country_low_amount_sum
Out[18]:
country sum_funded_amount sum_loan_amount
63 United States 839680.0 8628500.0
15 El Salvador 955275.0 3225050.0
26 Kenya 635725.0 2423475.0
10 Colombia 549150.0 1914600.0
1 Armenia 511900.0 1819275.0
3 Bolivia 425025.0 1523000.0
54 Tajikistan 346200.0 1245100.0
64 Vietnam 313775.0 1221500.0
61 Uganda 314275.0 1162450.0
48 Rwanda 267925.0 1110025.0
6 Cambodia 203725.0 1102550.0
43 Palestine 293050.0 1089000.0
46 Philippines 257425.0 853625.0
42 Pakistan 195475.0 831300.0
49 Samoa 179000.0 679600.0
40 Nicaragua 183175.0 632525.0
34 Mali 168050.0 625625.0
30 Lebanon 152300.0 535150.0
19 Guatemala 112100.0 452950.0
45 Peru 88200.0 443375.0
In [19]:
# namen für die Umschreibung der legende finden

barplot = px.bar(data_frame=df_country_low_amount_sum
                ,x="country"
                ,y=["sum_funded_amount", "sum_loan_amount"]
                ,title=f'Top {top_countries} Länder. Sortiert nach Summe der Zielbeträge pro Land. Alle Beträge in USD.'
                ,labels={"country":"Land", "value":"Summe der Beträge in USD"} # Beschriftungen anpassen
                ,barmode='group'
               )
In [20]:
print(barplot)
Figure({
    'data': [{'alignmentgroup': 'True',
              'hovertemplate': ('variable=sum_funded_amount<br>' ... 'äge in USD=%{y}<extra></extra>'),
              'legendgroup': 'sum_funded_amount',
              'marker': {'color': '#636efa', 'pattern': {'shape': ''}},
              'name': 'sum_funded_amount',
              'offsetgroup': 'sum_funded_amount',
              'orientation': 'v',
              'showlegend': True,
              'textposition': 'auto',
              'type': 'bar',
              'x': array(['United States', 'El Salvador', 'Kenya', 'Colombia', 'Armenia',
                          'Bolivia', 'Tajikistan', 'Vietnam', 'Uganda', 'Rwanda', 'Cambodia',
                          'Palestine', 'Philippines', 'Pakistan', 'Samoa', 'Nicaragua', 'Mali',
                          'Lebanon', 'Guatemala', 'Peru'], dtype=object),
              'xaxis': 'x',
              'y': array([839680., 955275., 635725., 549150., 511900., 425025., 346200., 313775.,
                          314275., 267925., 203725., 293050., 257425., 195475., 179000., 183175.,
                          168050., 152300., 112100.,  88200.]),
              'yaxis': 'y'},
             {'alignmentgroup': 'True',
              'hovertemplate': ('variable=sum_loan_amount<br>La' ... 'äge in USD=%{y}<extra></extra>'),
              'legendgroup': 'sum_loan_amount',
              'marker': {'color': '#EF553B', 'pattern': {'shape': ''}},
              'name': 'sum_loan_amount',
              'offsetgroup': 'sum_loan_amount',
              'orientation': 'v',
              'showlegend': True,
              'textposition': 'auto',
              'type': 'bar',
              'x': array(['United States', 'El Salvador', 'Kenya', 'Colombia', 'Armenia',
                          'Bolivia', 'Tajikistan', 'Vietnam', 'Uganda', 'Rwanda', 'Cambodia',
                          'Palestine', 'Philippines', 'Pakistan', 'Samoa', 'Nicaragua', 'Mali',
                          'Lebanon', 'Guatemala', 'Peru'], dtype=object),
              'xaxis': 'x',
              'y': array([8628500., 3225050., 2423475., 1914600., 1819275., 1523000., 1245100.,
                          1221500., 1162450., 1110025., 1102550., 1089000.,  853625.,  831300.,
                           679600.,  632525.,  625625.,  535150.,  452950.,  443375.]),
              'yaxis': 'y'}],
    'layout': {'barmode': 'group',
               'legend': {'title': {'text': 'variable'}, 'tracegroupgap': 0},
               'template': '...',
               'title': {'text': 'Top 20 Länder. Sortiert nach Summe der Zielbeträge pro Land. Alle Beträge in USD.'},
               'xaxis': {'anchor': 'y', 'domain': [0.0, 1.0], 'title': {'text': 'Land'}},
               'yaxis': {'anchor': 'x', 'domain': [0.0, 1.0], 'title': {'text': 'Summe der Beträge in USD'}}}
})
In [21]:
print(barplot.data[0].name)
sum_funded_amount

Plot zum Bewerten 2/3¶

In [22]:
#Create a 2x1 subplot

fig = make_subplots(rows=2, cols=1
                    ,shared_yaxes=True
                    ,subplot_titles=(f'Summe tatsächlich erhaltener Beträge und Summe der Zielbeträge',
                                     f'Nur die Summe tatsächlich erhaltener Beträge'))


# plotly express plots

barplot1 = px.bar(data_frame=df_country_low_amount_sum
                                ,x="country"
                                ,y=["sum_funded_amount", "sum_loan_amount"]
                                #,title=f'Top {top_countries} Länder. Sortiert nach Summe der Zielbeträge pro Land. Alle Beträge in USD.'
                                ,labels={"country":"Land", "value":"Summe der Beträge in USD", "variable":"Beträge"} # Beschriftungen anpassen
                               ,barmode='group'
                               )

newnames = {'sum_funded_amount':'Summe erhaltener Beträge', 'sum_loan_amount': 'Summe der Zielbeträge'}
# Alternative
barplot1.for_each_trace(lambda t: t.update(name = newnames[t.name]))

barplot2 = px.bar(data_frame=df_country_low_amount_sum
                    ,x="country"
                    ,y="sum_funded_amount"
                    #,title=f'Top {top_countries} Länder. Sortiert nach Summe der Zielbeträge pro Land. Alle Beträge in USD.'
                    ,labels={"country":"Land", "value":"Summe der Beträge in USD", "variable":"Beträge"} # Beschriftungen anpassen
                   ,barmode='group'
                   )




# plots mit figuren ogject

for traces in barplot1.data:
    fig.add_trace(traces, row=1, col=1)   
    
for traces in barplot2.data:
    fig.add_trace(traces, row=2, col=1)    

    
    
# Update title and heightdf
fig.update_layout(title_text=f'Top {top_countries} Länder. Sortiert nach Summe der Zielbeträge pro Land. Alle Beträge in USD.'
                  ,height=900)


# anzeigen

fig.show()


# Instead of setting the cell to Markdown, create Markdown from withnin a code cell!
# We can just use python variable replacement syntax to make the text dynamic
md("**Beschreibung** \n- In den Säulen sind die Summen der Beträge in USD abgetragen.\n- \
   Die Projekte die mit weniger als {}% des Zeilbetrages finanziert worden, wurden für jedes Land aufsummiert und als blaue Säulen eingetragen.\n- \
   Dementsprechend stehen die aufsummierten Zeilbeträge als rote Säulen gegenüber.\n- \
   Auffällig ist, dass in den USA ca. 8 Millionen USD nicht an die Projektinitiator*innen gebracht worden.\n- \
   Auf dem zweiten Subplot ist auch zu erkennen, dass die Summe erhaltener Beträge in El Salvador sogar höher ist als in USA.\n- \
   Summen der Zielbeträge fallen schneller ab als die Summen erhaltener Beträge".format(int(percent * 100) ))
Out[22]:

Beschreibung

  • In den Säulen sind die Summen der Beträge in USD abgetragen.
  • Die Projekte die mit weniger als 50% des Zeilbetrages finanziert worden, wurden für jedes Land aufsummiert und als blaue Säulen eingetragen.
  • Dementsprechend stehen die aufsummierten Zeilbeträge als rote Säulen gegenüber.
  • Auffällig ist, dass in den USA ca. 8 Millionen USD nicht an die Projektinitiator*innen gebracht worden.
  • Auf dem zweiten Subplot ist auch zu erkennen, dass die Summe erhaltener Beträge in El Salvador sogar höher ist als in USA.
  • Summen der Zielbeträge fallen schneller ab als die Summen erhaltener Beträge
In [23]:
# Schauen wir uns die USA genauer an

df_my_country = df.loc[df.loc[:,'country'] == 'United States',]
In [24]:
df_my_country_sum_funded_loan_amount = df_my_country.groupby(by='use', as_index=False).agg(sum_funded_amount = ('funded_amount','sum'), sum_loan_amount = ('loan_amount','sum')).sort_values(['sum_loan_amount'], ascending = False)[:top_usage]
df_my_country_sum_funded_loan_amount
Out[24]:
use sum_funded_amount sum_loan_amount
2190 kein_verwendungszweck 482525.0 738300.0
1695 gain working capital for my business 59200.0 94075.0
5202 to purchase inventory 30925.0 33850.0
1381 expand my business 9000.0 26350.0
575 boost our advertising and gain working capital... 200.0 22000.0
5103 to purchase additional inventory 17900.0 20775.0
1761 get into a clothing trade show that can help e... 10025.0 20000.0
4107 repair or replace outdated equipment, boost ou... 1050.0 20000.0
2043 improve my business through marketing, remodel... 650.0 20000.0
1710 gain working capital for my business, boost ou... 325.0 20000.0
In [25]:
barplot = px.bar(data_frame=df_my_country_sum_funded_loan_amount
                ,x=["sum_funded_amount", "sum_loan_amount"]                 
                ,y="use"
                ,title=f'Top {top_usage} Verwendungszwecke in den USA. Nach Summe der Zielbeträge sortiert.'
                ,labels={"use":"Verwendungszweck", "value":"Summe der Beträge in USD", "variable":"Beträge"} # Beschriftungen anpassen
                ,barmode='group'
                ,orientation='h'  
                )

newnames = {'sum_funded_amount':'Summe erhaltener Beträge', 'sum_loan_amount': 'Summe der Zielbeträge'}
barplot.for_each_trace(lambda t: t.update(name = newnames[t.name]))

barplot.update_layout(yaxis={'categoryorder':'total ascending'}) 

barplot.show()
In [26]:
# Schauen wir uns die Darlehensnehmer in den USA genauer an

top_total_borrowers = 5
df_sum_funded_loan_amount = df.loc[cond_low_amount,].groupby(by='borrower_total', as_index=False).agg(sum_funded_amount = ('funded_amount','sum'), sum_loan_amount = ('loan_amount','sum')).sort_values(['sum_loan_amount'], ascending= False)[:top_total_borrowers]
df_sum_funded_loan_amount
Out[26]:
borrower_total sum_funded_amount sum_loan_amount
1 1 6533655.0 29214350.0
0 -1 102695.0 1120250.0
4 4 212700.0 840375.0
3 3 208100.0 834875.0
5 5 206050.0 767175.0
In [27]:
diff = df_sum_funded_loan_amount.loc[df_sum_funded_loan_amount.loc[:,'borrower_total' ] == 1, 'sum_loan_amount'] - df_sum_funded_loan_amount.loc[df_sum_funded_loan_amount.loc[:,'borrower_total' ] == 1, 'sum_funded_amount']
print(f' Insgesammt sind {round(diff[1] / 1_000_000, 1)} Millionen USD nicht an die Projektinitiator*innen gebracht worden.')
 Insgesammt sind 22.7 Millionen USD nicht an die Projektinitiator*innen gebracht worden.

Plot zum Bewerten 3/3¶

In [28]:
barplot = px.bar(data_frame=df_sum_funded_loan_amount
                ,x="borrower_total"                 
                ,y=["sum_funded_amount", "sum_loan_amount"]                 
                ,title=f'Anzahl der Top {top_total_borrowers} der Darlehensnehmer.<br>Sortiert nach Summe der Zielbeträge pro Anzahl der Darlehensnehmer. Alle Beträge in USD.'
                ,labels={"borrower_total":"Anzahl der Darlehensnehmer", "value":"Summe der Beträge in USD", "variable":"Beträge"} # Beschriftungen anpassen
                ,barmode='group'
                #,orientation='h'  
                ,height=800
                )

newnames = {'sum_funded_amount':'Summe erhaltener Beträge', 'sum_loan_amount': 'Summe der Zielbeträge'}
# barplot.data[0].name = newnames['sum_funded_amount']
# barplot.data[1].name = newnames['sum_loan_amount']

# Alternative:
barplot.for_each_trace(lambda t: t.update(name = newnames[t.name]))

y_wert = int(df_sum_funded_loan_amount.loc[df_sum_funded_loan_amount.loc[:, 'borrower_total'] == -1,"sum_loan_amount"])

barplot.add_annotation(x='-1', 
                             y=y_wert,
                             
                             text='Die NaNs beim Preprocessing mit (-1) befüllt',
                             
                             # textangle: Legt den Winkel fest, 
                             # in dem der "Text" in Bezug auf die zur Horizontalen gezeichnet wird.
                             #textangle=0,
                             
                             # ax: Legt die Neigung ses Pfeils fest. 
                             ax=-10,
                             
                             # showarrow: -> Pfeil anzeigen
                             # Legt fest, ob die Anmerkung mit einem Pfeil gezeichnet einem Pfeil gezeichnet wird. 
                             # Wenn True, wird `Text` in der Nähe des Pfeils platziert Ende platziert. 
                             # Wenn False, wird `Text` an den angegebenen `x` und `y` ausgerichtet bereitgestellt.
                             showarrow=True,
                             
                             # Pfeilspitze: Legt den Stil der Pfeilspitze fest
                             arrowhead=2
                            )



barplot.show()


# Instead of setting the cell to Markdown, create Markdown from withnin a code cell!
# We can just use python variable replacement syntax to make the text dynamic
md("**Beschreibung** \n- In den Säulen sind die Summen der Beträge in USD abgetragen.\n- \
   Die Projekte die mit weniger als {}% des Zeilbetrages finanziert worden, wurden für jede Darlehensnehmer Gruppe aufsummiert und als blaue Säulen eingetragen.\n- \
   Dementsprechend stehen die aufsummierten Zeilbeträge als rote Säulen gegenüber.\n- \
   Auffällig ist, dass ca. {} Millionen USD nicht an den einen Projektinitiator*innen gebracht worden.\n- \
   Somit ist die größe der Gruppe der Darlehensnehmer wichtig.\n- \
   Offensichtlich ist es aber auch möglich den Geschlecht und somit auch die Anzahl der Darlehensnehmer zu verweigern und damit vielleicht auch eine bessere Chance zu bekommen ein Darlehen zu erhalten.\n  -\
   Zu beachten ist aber auch, dass diese Gruppe den Verwendungszweck und Region nicht angegeben haben.\n -\
   Somit fällt wieder auf, dass ein Klärungsbedarf besteht ob dies ein Systembug ist oder nicht.".format(int(percent * 100), round(diff[1] / 1_000_000, 1) ))
Out[28]:

Beschreibung

  • In den Säulen sind die Summen der Beträge in USD abgetragen.
  • Die Projekte die mit weniger als 50% des Zeilbetrages finanziert worden, wurden für jede Darlehensnehmer Gruppe aufsummiert und als blaue Säulen eingetragen.
  • Dementsprechend stehen die aufsummierten Zeilbeträge als rote Säulen gegenüber.
  • Auffällig ist, dass ca. 22.7 Millionen USD nicht an den einen Projektinitiator*innen gebracht worden.
  • Somit ist die größe der Gruppe der Darlehensnehmer wichtig.
  • Offensichtlich ist es aber auch möglich den Geschlecht und somit auch die Anzahl der Darlehensnehmer zu verweigern und damit vielleicht auch eine bessere Chance zu bekommen ein Darlehen zu erhalten.
    • Zu beachten ist aber auch, dass diese Gruppe den Verwendungszweck und Region nicht angegeben haben.
    • Somit fällt wieder auf, dass ein Klärungsbedarf besteht ob dies ein Systembug ist oder nicht.
In [29]:
# https://plotly.com/python/treemaps/
fig = px.treemap(df
                 ,path=[px.Constant("Sektoren"), 'sector', 'activity']
                 ,values='funded_amount'
                )

fig.update_layout(margin = dict(t=50, l=25, r=25, b=25))

fig.show()
In [30]:
# Grafik erstellen

fig = px.scatter(df_my_country
                 ,x="funded_amount"
                 ,y="lender_count"
                  ,color="sector"                  
                 )
fig.show()
In [31]:
sns.boxplot(x="sector", y="funded_amount", data=df_my_country)
Out[31]:
<AxesSubplot:xlabel='sector', ylabel='funded_amount'>
In [32]:
sns.violinplot(x='sector', y='funded_amount',data=df_my_country)
Out[32]:
<AxesSubplot:xlabel='sector', ylabel='funded_amount'>
In [33]:
sns.lmplot(x="funded_amount", y="lender_count",hue='sector',data=df_my_country)
Out[33]:
<seaborn.axisgrid.FacetGrid at 0x1f108165a00>
In [34]:
# Nach sector, repayment_interval gruppiert und nach Anzahl sortiert

df_sector_repayment_interval = df.groupby(by=['sector','repayment_interval'], as_index=False).agg(count = ('repayment_interval','count'))
matrix = pd.pivot_table(df_sector_repayment_interval, index='sector', columns='repayment_interval', values='count', sort=False)#.fillna(0)
matrix
Out[34]:
repayment_interval bullet irregular monthly weekly
sector
Agriculture 43963.0 47524.0 88776.0 39.0
Arts 1475.0 4636.0 5934.0 15.0
Clothing 1048.0 13559.0 17997.0 138.0
Construction 294.0 1549.0 4414.0 11.0
Education 2437.0 4351.0 24225.0 NaN
Entertainment 155.0 226.0 449.0 NaN
Food 4607.0 75914.0 56039.0 97.0
Health 138.0 1659.0 7413.0 13.0
Housing 880.0 8451.0 24400.0 NaN
Manufacturing 451.0 2439.0 3318.0 NaN
Personal Use 4791.0 4083.0 27511.0 NaN
Retail 4940.0 73646.0 45784.0 124.0
Services 5083.0 12552.0 27352.0 153.0
Transportation 410.0 6405.0 8691.0 12.0
Wholesale 56.0 164.0 414.0 NaN
In [35]:
sns.set(rc={'figure.figsize':(15.7, 15.27)})
ax = sns.heatmap(matrix, cmap="coolwarm", annot=True, fmt="")
In [36]:
g = sns.FacetGrid(df_my_country
                  ,col="repayment_interval"
                  ,height=5
                  #,aspect=0.3
                  ,hue="sector"
                 )

g.map(sns.scatterplot, "funded_amount", "lender_count")

g.add_legend()
Out[36]:
<seaborn.axisgrid.FacetGrid at 0x1f109d4df40>

Dashboard¶

In [37]:
# App erstellen

my_app = JupyterDash(__name__)

# Layout erstellen

my_app.layout = html.Div([
    
                    # Label - Titel für die Plots
                    html.Label(
                                id="sl_label"
                                ,children = f'Top {top_countries} Länder. Sortiert nach Summe der Zielbeträge pro Land. Alle Beträge in USD. \
                                             Die Projekte die mit weniger als (die im Slider ausgewählte Prozentzahl) des Zeilbetrages finanziert worden, wurden für jedes Land aufsummiert und als Säulen eingetragen'
                                ,style={"text-align":"center"}  
                               )  
    
                    # breack - Zeilenabstände zw. den einzelnen Parametern
                    ,html.Br()  
    
                    # breack - Zeilenabstände zw. den einzelnen Parametern
                    ,html.Br()      
    
                    # Slider
                    ,dcc.Slider(
                                id="lb_slider"
                                ,min = 0
                                ,max = 100
                                ,step=5
                                #,marks={i: '{}'.format(i) for i in range(1, 20+1)},
                                ,value=20
                                )  

    
                     # Grafik
                     ,dcc.Graph(id="sum_plot",  # id wird später für den callback benötigt
                              figure={}   # übernimmt den plot
                              )  

])
    
                   
# callback erstellen
@my_app.callback(
                 Output(component_id="sum_plot", component_property="figure"),
                 Input(component_id="lb_slider", component_property="value")
                )


# Erstellen der Update-Funktion
def update_label(selected_slyder):   # die Anzahl der Parameter hängt von der Anzahl der Inputs ab
                                   # hier 1 Input --> 1 Parameter wird an die update-Funktion übergeben
                                   # Was wird übergeben?  component_property des Input
    
    # Condition selektieren - innerhalb der update-Funktion
    
    cond_low_amount_sel = df.loc[:,'funded_amount'] / df.loc[:,'loan_amount'] <= selected_slyder / 100
    
    # Daten gruppieren
    
    df_sel_group = df.loc[cond_low_amount_sel,].groupby(by='country', as_index=False).agg(sum_funded_amount = ('funded_amount','sum'), sum_loan_amount = ('loan_amount','sum')).sort_values(['sum_loan_amount'], ascending= False)[:top_countries]
    
    #Create a 2x1 subplot

    fig = make_subplots(rows=2, cols=1
                        ,shared_yaxes=True
                        ,subplot_titles=(f'Summe tatsächlich erhaltener Beträge und Summe der Zielbeträge',
                                         f'Nur die Summe tatsächlich erhaltener Beträge'))


    # plotly express plots

    barplot1 = px.bar(data_frame=df_sel_group
                                    ,x="country"
                                    ,y=["sum_funded_amount", "sum_loan_amount"]
                                    #,title=f'Top {top_countries} Länder. Sortiert nach Summe der Zielbeträge pro Land. Alle Beträge in USD.'
                                    ,labels={"country":"Land", "value":"Summe der Beträge in USD", "variable":"Beträge"} # Beschriftungen anpassen
                                   ,barmode='group'
                                   )

    newnames = {'sum_funded_amount':'Summe erhaltener Beträge', 'sum_loan_amount': 'Summe der Zielbeträge'}
    barplot1.for_each_trace(lambda t: t.update(name = newnames[t.name]))

    barplot2 = px.bar(data_frame=df_sel_group
                        ,x="country"
                        ,y="sum_funded_amount"
                        #,title=f'Top {top_countries} Länder. Sortiert nach Summe der Zielbeträge pro Land. Alle Beträge in USD.'
                        ,labels={"country":"Land", "value":"Summe der Beträge in USD", "variable":"Beträge"} # Beschriftungen anpassen
                       ,barmode='group'
                       )

    # plots mit figuren ogject

    for traces in barplot1.data:
        fig.add_trace(traces, row=1, col=1)   

    for traces in barplot2.data:
        fig.add_trace(traces, row=2, col=1)    



    # Update title and heightdf
    fig.update_layout(#title_text=f'Top {top_countries} Länder. Sortiert nach Summe der Zielbeträge pro Land. Alle Beträge in USD.'
                      height=600)

    return fig     # Rückgabewert ist ein dictionary, welches an Output component_property übergeben wird


# App ausführen

if __name__ == '__main__':
    my_app.run_server(mode='inline')
In [ ]: